package utils

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"gitee.com/jiangjiali/z-tcp/helper/gmsm/sm4"
	"reflect"
	"unsafe"

	"gitee.com/jiangjiali/z-tcp/helper/gmsm/sm2"
	"gitee.com/jiangjiali/z-tcp/helper/gmsm/x509"
)

// ServerPem 服务端的钥匙
type ServerPem struct {
	UA        []byte `json:"ua"`
	Sign      []byte `json:"sign"`
	PublicKey []byte `json:"public-key"`
}

// sm4使用的KEY
var key = []byte("B45A0148BP65L00Q")

// GeneratePem 获取服务端密钥对
func GeneratePem(connId int64) (ServerPem, *sm2.PrivateKey) {
	//生成密钥对
	privateKey, _ := sm2.GenerateKey(rand.Reader)

	var ua = Int64ToBytes(connId)
	sign, _ := privateKey.Sign(rand.Reader, ua, nil) //sm2签名
	pemPublic, _ := x509.WritePublicKeyToPem(&privateKey.PublicKey)
	serverpem := ServerPem{UA: Int64ToBytes(connId), Sign: sign, PublicKey: pemPublic}

	return serverpem, privateKey
}

// Int64ToBytes int64转bytes字符
func Int64ToBytes(i int64) []byte {
	var buf = make([]byte, 8)
	binary.BigEndian.PutUint64(buf, uint64(i))
	return buf
}

// BytesToInt64 bytes字符转int64
func BytesToInt64(buf []byte) int64 {
	return int64(binary.BigEndian.Uint64(buf))
}

// IsNil 判断interface{} 是否为空
func IsNil(i interface{}) bool {
	defer func() {
		recover()
	}()
	vi := reflect.ValueOf(i)
	return vi.IsNil()
}

// StrToBytes 字符str转bytes
func StrToBytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s))
	b := [3]uintptr{x[0], x[1], x[1]}
	return *(*[]byte)(unsafe.Pointer(&b))
}

// BytesToStr bytes转str字符
func BytesToStr(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}

// Sm4En 加密
func Sm4En(value []byte) []byte {
	// sm4Ecb模式pksc7填充加密
	ecbMsg, err := sm4.Sm4Ecb(key, value, true)
	if err != nil {
		return nil
	}
	return ecbMsg
}

// Sm4Dec 解密
func Sm4Dec(value []byte) []byte {
	// sm4Ecb模式pksc7填充解密
	ecbDec, err := sm4.Sm4Ecb(key, value, false)
	if err != nil {
		return nil
	}
	return ecbDec
}

// NChars 创建相同字符的字符串
func NChars(b []byte, n int) string {
	//两个字节一个字符
	return string(bytes.Repeat(b,n*2))
}